package it.polimi.traveldream.beans;

import it.polimi.traveldream.dto.AccomodationDTO;
import it.polimi.traveldream.dto.DefaultPackageDTO;
import it.polimi.traveldream.dto.DetailedDefaultPackageDTO;
import it.polimi.traveldream.dto.ScheduleDTO;
import it.polimi.traveldream.dto.TransportDTO;
import it.polimi.traveldream.ejb.DefaultPackageManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;

@ManagedBean(name = "defaultPackageBean")
@ViewScoped
public class DefaultPackageBean {

	@EJB
	private DefaultPackageManager manager;

	private DetailedDefaultPackageDTO pack;

	public DefaultPackageBean() {
	}

	@PostConstruct
	public void init() {
		Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext()
				.getRequestParameterMap();

		String id = params.get("packageId");

		if (id != null && !id.isEmpty()) {
			this.pack = this.findPackage(Integer.valueOf(id));
		}

		if (this.pack == null) {
			this.pack = new DetailedDefaultPackageDTO();
		}
	}

	public DetailedDefaultPackageDTO getPack() {
		return this.pack;
	}

	public void setPack(DetailedDefaultPackageDTO pack) {
		this.pack = pack;
	}

	public String save() {
		if (this.pack.getGoing() == null || this.pack.getGoing().getId() == null) {
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Selezionare un viaggio di andata!", ""));
		} else if (this.pack.getBack() == null || this.pack.getBack().getId() == null) {
			FacesContext.getCurrentInstance().addMessage(
					null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR,
							"Selezionare un viaggio di ritorno!", ""));
		} else if (this.pack.getAccomodation() == null
				|| this.pack.getAccomodation().getId() == null) {
			FacesContext.getCurrentInstance().addMessage(null,
					new FacesMessage(FacesMessage.SEVERITY_ERROR, "Selezionare un alloggio!", ""));
		} else {
			this.manager.save(this.pack);
		}
		return "/employee/packages/list?faces-redirect=true";
	}

	public void changeCity() {
		this.pack.setGoing(null);
		this.pack.setBack(null);
		this.pack.setAccomodation(null);
	}

	public void chooseGoing() {
		Map<String, List<String>> param = new HashMap<>();

		List<String> list = new ArrayList<>();
		list.add(this.pack.getCity());
		param.put("destination", list);

		list = new ArrayList<>();
		TransportDTO transportDTO = this.pack.getGoing();
		if (transportDTO != null && transportDTO.getId() != null) {
			list.add(String.valueOf(transportDTO.getId()));
		}
		param.put("selected", list);

		RequestContext.getCurrentInstance().openDialog("/goingDialog", null, param);
	}

	public void selectGoing(SelectEvent event) {
		this.pack.setGoing((TransportDTO) event.getObject());
		if (this.pack.getBack() == null
				|| this.pack.getGoing() == null
				|| (!this.pack.getGoing().getOrigin().equals(this.pack.getBack().getDestination()) || !this.pack
						.getGoing().getDestination().equals(this.pack.getBack().getOrigin()))) {
			this.pack.setBack(null);
		}
	}

	public void chooseBack() {
		Map<String, List<String>> param = new HashMap<>();

		List<String> list = new ArrayList<>();
		list.add(this.pack.getGoing().getDestination());
		param.put("origin", list);

		list = new ArrayList<>();
		list.add(this.pack.getGoing().getOrigin());
		param.put("destination", list);

		list = new ArrayList<>();
		TransportDTO transportDTO = this.pack.getBack();
		if (transportDTO != null && transportDTO.getId() != null) {
			list.add(String.valueOf(transportDTO.getId()));
		}
		param.put("selected", list);

		RequestContext.getCurrentInstance().openDialog("/backDialog", null, param);
	}

	public void selectBack(SelectEvent event) {
		this.pack.setBack((TransportDTO) event.getObject());
	}

	public void chooseAccomodation() {
		Map<String, List<String>> param = new HashMap<>();

		List<String> list = new ArrayList<>();
		list.add(this.pack.getCity());
		param.put("city", list);

		list = new ArrayList<>();
		AccomodationDTO accomodationDTO = this.pack.getAccomodation();
		if (accomodationDTO != null && accomodationDTO.getId() != null) {
			list.add(String.valueOf(accomodationDTO.getId()));
		}
		param.put("selected", list);

		RequestContext.getCurrentInstance().openDialog("/accomodationDialog", null, param);
	}

	public void selectAccomodation(SelectEvent event) {
		this.pack.setAccomodation((AccomodationDTO) event.getObject());
	}

	public void chooseActivity(Integer day) {
		Map<String, List<String>> param = new HashMap<>();

		List<String> list = new ArrayList<>();
		list.add(this.pack.getCity());
		param.put("city", list);

		list = new ArrayList<>();
		list.add(day.toString());
		param.put("day", list);

		list = new ArrayList<>();
		ScheduleDTO scheduleDTO = this.pack.getSchedule().get(day);
		if (scheduleDTO != null)
			list.add(scheduleDTO.getActivity().getId().toString());
		param.put("selected", list);

		RequestContext.getCurrentInstance().openDialog("/activitiesDialog", null, param);
	}

	public void selectActivity(SelectEvent event) {
		this.pack.addSchedule((ScheduleDTO) event.getObject());
	}

	public List<Integer> getDaysList() {
		List<Integer> list = new ArrayList<>();
		if (this.pack.getDuration() != null) {
			// la durata è espressa in notti, i giorni iniziano dallo 0 (giorno
			// dell' andata)
			// le attività sono pianificate nei giorni da 1 a n-1 (si escludono
			// il giorno di arrivo e partenza)
			for (int i = 1; i < this.pack.getDuration(); i++) {
				list.add(i);
			}
		}
		return list;
	}

	public List<DefaultPackageDTO> getPackages() {
		return this.manager.getPackages();
	}

	public DetailedDefaultPackageDTO findPackage(Integer id) {
		return this.manager.findPackage(id);
	}

	public String remove(DefaultPackageDTO packageDTO) {
		this.pack = this.findPackage(packageDTO.getId());
		this.pack.setValid(false);
		this.save();
		return null;
	}

	public List<ScheduleDTO> getActivityList() {
		return new ArrayList<>(this.pack.getSchedule().values());
	}

}
